package com.duobaoyu.chatwebsocket.handler;

import com.alibaba.fastjson.JSON;
import com.duobaoyu.chatwebsocket.dto.*;
import com.duobaoyu.chatwebsocket.enums.MsgActionEnum;
import com.duobaoyu.chatwebsocket.enums.SourceTypeEnum;
import com.duobaoyu.chatwebsocket.netty.UserChannelRel;
import com.duobaoyu.chatwebsocket.util.JsonObjectUtil;
import com.duobaoyu.chatwebsocket.util.JsonUtils;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;

/**
 * 发送websocket新消息handler
 *
 * @author guiguan
 * @date 2019/10/14 9:49
 */
@Component
@Slf4j
public class ChatWriteHandler {

    /**
     * 统一发送方法
     *
     * @param dto 消息对象
     */
    private void sendMsgToEmp(WebSocketBaseDto dto, String channelId) {
        // 从全局用户Channel关系中获取接受方的channel
        Channel receiverChannel = UserChannelRel.channelIdWithChannel.get(channelId);
        log.info("receiverChannel : {}",JSON.toJSON(receiverChannel));
        if (receiverChannel != null) {
            if (receiverChannel.isActive() && receiverChannel.isWritable()) {
                receiverChannel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(dto)));
            }
        }else{
            log.warn("向前端发送消息事件：{} ,dto{}", channelId, JSON.toJSONString(dto));
        }
    }


    /**
     * 用户消息发送到顾问
     *
     * @param dto MessageDto
     */
    public void weChatToEmp(WebSocketMessageDto dto, String channelId) {
        dto.setEvent(MsgActionEnum.CUSTOMER_MSG.getEvent());
        this.sendMsgToEmp(dto, channelId);
    }

    /**
     * 发送登录结果
     *
     * @param webSocketResultDto 结果
     */
    public void loginResultToSale(WebSocketResultDto webSocketResultDto, String channelId) {
        String event = MsgActionEnum.LOGIN_RESULT.getEvent();
        webSocketResultDto.setEvent(event);
        this.sendMsgToEmp(webSocketResultDto, channelId);
    }

    public void messageResult(WebSocketResultDto dto, String channelId) {
        dto.setEvent(MsgActionEnum.MSG_RESULT.getEvent());
        this.sendMsgToEmp(dto, channelId);
    }


    /**
     * 发送给前端通知其跳转登陆页面
     *
     * @param channel 需要断开的通道
     */
    public void needLogin(Channel channel) {
        // 从全局用户Channel关系中获取接受方的channel
        WebSocketResultDto webSocketResultDto = new WebSocketResultDto();
        webSocketResultDto.setEvent(MsgActionEnum.NEED_LOGIN.getEvent());
        webSocketResultDto.setMsg("您的账号状态发生变化，请重新登录");
        if (channel != null) {
            if (channel.isActive() && channel.isWritable()) {
                channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(webSocketResultDto)));
            }
        }
    }

    /**
     * @param channelId syncMsg同步消息
     */
    public void syncMsg(String channelId, WebSocketMessageDto webSocketMessageDto) {
        // 从全局用户Channel关系中获取接受方的channel
        if (channelId != null) {
            Channel channel = UserChannelRel.channelIdWithChannel.get(channelId);
            if (StringUtils.isEmpty(channel)) {
                return;
            }
            webSocketMessageDto.setEvent(MsgActionEnum.SYNC_MSG.getEvent());
            if (channel.isActive() && channel.isWritable()) {
                channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(webSocketMessageDto)));
            }
        } else {
            log.error("syncMsg channelId is null");
        }
    }

    /**
     * 发送除了聊天系统以外的消息
     *
     * @param content   内容
     * @param channelId 通道id
     */
    public void otherMsg(Object content, String channelId) {
        Channel receiverChannel = UserChannelRel.channelIdWithChannel.get(channelId);
        if (receiverChannel != null) {
            log.info("向前端发送other消息 ,dto{}", JSON.toJSONString(content));
            if (receiverChannel.isWritable() && receiverChannel.isActive()) {
                receiverChannel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(content)));
            }
        }
    }

    /**
     * 游客登录回调
     */
    public void userConnect(String channelId, WebSocketResultDto webSocketResultDto) {
        if (!StringUtils.isEmpty(channelId)) {
            Channel channel = UserChannelRel.channelIdWithChannel.get(channelId);
            //游客已断开连接，直接返回
            if (channel == null) {
                log.info("this docker has not that channelId");
                return;
            }
            webSocketResultDto.setEvent(MsgActionEnum.CLIENT_LOGIN_RESULT.getEvent());
            log.info("游客成功登录{},{}",channelId,webSocketResultDto);
            if (channel.isWritable() && channel.isActive()) {
                log.info("user success login{}",webSocketResultDto);
                channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(webSocketResultDto)));
            }
        }

    }

    /**
     * 顾问发送消息到游客的客户端
     *
     * @param webSocketMqDto
     */
    public void toClient(WebSocketMqDto webSocketMqDto) {
        // 获取消息体里面要发送的用户
        if (!StringUtils.isEmpty(webSocketMqDto.getTo())) {
            // 获得该用户已建立的通道数组
            ArrayList<Channel> channels = UserChannelRel.userIdWithChannelList.get(Long.parseLong(webSocketMqDto.getTo()));
            if (CollectionUtils.isEmpty(channels)) {
                return;
            }
            // chat向ws发送的消息体直接发给前端
            WebSocketMessageDto dto = new WebSocketMessageDto();
            dto.setData(webSocketMqDto.getContent());
            dto.setSource(SourceTypeEnum.ADVISER.getCode());
            dto.setEvent(MsgActionEnum.RECEIVE_SALE_MESSAGE.getEvent());
            for (int i=0;i<channels.size();i++){
            if (channels.get(i).isActive() && channels.get(i).isWritable()) {
                channels.get(i).writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(dto)));
            }
        }}
    }

    /**
     * 游客发送消息的结果
     * @param webSocketUserResultDto
     */
    public void toClientResult(WebSocketResultDto webSocketUserResultDto,String to) {

        if (!StringUtils.isEmpty(to)) {
            // 获得该用户已建立的通道数组
            ArrayList<Channel> channels = UserChannelRel.userIdWithChannelList.get(Long.parseLong(to));
            if (CollectionUtils.isEmpty(channels)) {
                return;
            }
            // chat向ws发送的消息体直接发给前端
            webSocketUserResultDto.setEvent(MsgActionEnum.CLIENT_MSG_RESULT.getEvent());
            for (int i=0;i<channels.size();i++){
                if (channels.get(i).isActive() && channels.get(i).isWritable()) {
                    channels.get(i).writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(webSocketUserResultDto)));
                }
            }}

    }

    public void labelMsgToEmp(WebSocketMessageDto<ChatContentDto> dto, String channelId) {
        dto.setEvent(MsgActionEnum.LABEL_MSG.getEvent());


        this.sendMsgToEmp(dto, channelId);
    }

    /**
     * 向顾问发送 关闭接客开关事件
     *
     * @param dto       消息对象
     * @param channelId 通道id
     * @author liuyintao
     */
    public void saleCloseReceptionSwitchToEmp(WebSocketMessageDto<ChatContentDto> dto, String channelId) {
        dto.setEvent(MsgActionEnum.SALE_CLOSE_RECEPTION_SWITCH.getEvent());
        this.sendMsgToEmp(dto, channelId);
    }

    /**
     * 向顾问发送 打开接客开关事件
     *
     * @param dto       消息对象
     * @param channelId 通道id
     * @author liuyintao
     */
    public void saleOpenReceptionSwitchToEmp(WebSocketMessageDto<ChatContentDto> dto, String channelId) {
        dto.setEvent(MsgActionEnum.SALE_OPEN_RECEPTION_SWITCH.getEvent());
        this.sendMsgToEmp(dto, channelId);
    }
}
